package src.com.server.service;

import src.com.qqcommon.Message;
import src.com.qqcommon.MessageType;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Objects;

/**
 * 该类的一个对象和客户端保持连接
 */
public class ServerConnectClientThread extends Thread{
    private Socket socket;
    private String userId; // 连接到服务端的用户id

    public ServerConnectClientThread(Socket socket, String userId) {
        this.socket = socket;
        this.userId = userId;
    }

    public Socket getSocket() {
        return socket;
    }

    @Override
    public void run() { // 发送或接收与客户端的通信
        while (true) {
            try {
                System.out.println("服务端和客户端 " + userId + " 保持通信！");
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                Message message = (Message) ois.readObject();
                // 根据MessageType做相应的业务处理
                if (message.getMesType().equals(MessageType.MESSAGE_GET_ONLINE_FRIEND)) {
                    // 客户端请求在线用户列表
                    System.out.println(message.getGetter() + "请求在线用户列表");
                    String onlineUsers = ManageClientThreads.getOnlineUsers();
                    // 构建一个Message对象
                    Message message2 = new Message();
                    message2.setMesType(MessageType.MESSAGE_RET_ONLINE_FRIEND);
                    message2.setContent(onlineUsers);
                    message2.setGetter(message.getGetter());
                    // 返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(message2);
                } else if (message.getMesType().equals(MessageType.MESSAGE_COMM_MES)) { // 转发私聊消息
                    // 根据message对象获取getterId 再获取其对应的线程
                    ServerConnectClientThread getterThread =
                            ManageClientThreads.getServerConnectClientThread(message.getGetter());
                    // 得到对应socket的对象输出流 将message对象转发给指定的客户端
                    System.out.println("just for test: " + (getterThread.socket == getterThread.getSocket()));
                    ObjectOutputStream oos = new ObjectOutputStream(getterThread.getSocket().getOutputStream());
                    oos.writeObject(message); // 转发私聊消息 （待添加功能：离线转发文件或消息 借助于数据库）

                } else if (message.getMesType().equals(MessageType.MESSAGE_TO_ALL_MES)) { // 群发消息
                    // 需要遍历管理线程的集合， 给所有除了自己以外的socket转发message对象
                    HashMap<String, ServerConnectClientThread> hashMap = ManageClientThreads.getHm();
                    Iterator<String> iterator = hashMap.keySet().iterator();
                    while (iterator.hasNext()) {
                        // 去除在线用户Id
                        String onlineId = iterator.next();
                        if (!onlineId.equals(message.getSender())) { // 排除群发消息的用户
                            // 进行message对象转发
                            ObjectOutputStream oos =
                                    new ObjectOutputStream(hashMap.get(onlineId).getSocket().getOutputStream());
                            oos.writeObject(message);
                        }
                    }

                } else if (message.getMesType().equals(MessageType.MESSAGE_FILE_MES)) { // 转发文件
                    ObjectOutputStream oos = new ObjectOutputStream
                            (ManageClientThreads.getServerConnectClientThread(message.getGetter()).getSocket().getOutputStream());
                    oos.writeObject(message);

                } else if (message.getMesType().equals(MessageType.MESSAGE_CLIENT_EXIT)) { // 客户端退出
                    System.out.println(message.getSender() + " 退出");
                    // 将与这个客户端通信的线程从HashMap集合中移除
                    ManageClientThreads.removeServerConnectClientThread(message.getSender());
                    // 关闭socket
                    socket.close();
                    // 退出线程
                    break;
                } else {
                    System.out.println("其他类型 暂时不处理。");
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

        }
    }
}
